﻿using System.Collections.Generic;
using Common.Logging;
using NHibernate;
using Spring.Data.NHibernate;
using Spring.Data.NHibernate.Generic.Support;

namespace Framework.Core.Domain.Dao.SpringNHB
{
    public class SpringNHBDaoBase<T, IDT> : HibernateDaoSupport, IDaoBase<T, IDT>
    {
        public SpringNHBDaoBase()
        {
            Logger = LogManager.GetLogger(this.ToString());
        }

        #region IGenericDao<T,IDT> 成员

        public T GetById(IDT entityId, bool shouldLock)
        {
            T re = HibernateTemplate.Load<T>(entityId);
            try
            {
               return re;
            }
            catch (NHibernate.ObjectNotFoundException)
            {
                return default(T);
            }
        }

        public IList<T> GetAll()
        {
            return HibernateTemplate.LoadAll<T>();
        }

        public void Save(T entity)
        {
            HibernateTemplate.Save(entity);
        }

        public void Update(T entity)
        {
            HibernateTemplate.Update(entity);
        }

        public void SaveOrUpdate(T entity)
        {
            HibernateTemplate.SaveOrUpdate(entity);
        }

        public void Delete(T entity)
        {
            HibernateTemplate.Delete(entity);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="conditions"></param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <param name="sortInfo"></param>
        /// <returns></returns>
        public IList<T> GetByConditions(List<string> conditions, int startIndex, int count, SortInfo sortInfo)
        {
            string alias = typeof (T).Name.ToLower();
            string hsql = string.Format("From {0} as {1} Where 1=1", typeof (T), alias);
            if (conditions != null)
            {
                foreach (string condition in conditions)
                {
                    hsql += " " + condition.Trim();
                }
            }
            if (sortInfo != null)
            {
                if (!string.IsNullOrEmpty(sortInfo.Field))
                {
                    hsql += string.Format(" Order By {0}.{1} {2}", alias, sortInfo.Field, sortInfo.Direction);
                }
            }
            IList<T> results = new List<T>();
            IQuery query = SessionFactoryUtils.GetSession(HibernateTemplate.SessionFactory, true).CreateQuery(hsql);
            if (count > 0)
            {
                query.SetFirstResult(startIndex);
                query.SetMaxResults(count);
                results = query.List<T>();
            }
            else if (count < 0)
            {
                results = query.List<T>();
            }
            return results;
        }

        public int GetCountByConditions(List<string> conditions)
        {
            string hsql = string.Format("Select count(*) From {0} as {1} Where 1=1 ", typeof (T),
                                        typeof (T).Name.ToLower());

            if (conditions != null)
            {
                foreach (string condition in conditions)
                {
                    hsql += condition;
                }
            }

            IQuery query = SessionFactoryUtils.GetSession(HibernateTemplate.SessionFactory, true).CreateQuery(hsql);
            object o = query.UniqueResult();
            return o == null ? 0 : int.Parse(o.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hql"></param>
        /// <param name="conditions"></param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <param name="sortInfo"></param>
        /// <returns></returns>
        public IList<T> GetByConditions(string hql, List<string> conditions, int startIndex, int count,
                                        SortInfo sortInfo)
        {
            if (conditions != null)
            {
                foreach (string condition in conditions)
                {
                    hql += " " + condition.Trim();
                }
            }
            if (sortInfo != null)
            {
                if (!string.IsNullOrEmpty(sortInfo.Field))
                {
                    hql += string.Format(" Order By {0} {1}", sortInfo.Field, sortInfo.Direction);
                }
            }
            IQuery query = SessionFactoryUtils.GetSession(HibernateTemplate.SessionFactory, true).CreateQuery(hql);
            query.SetFirstResult(startIndex);
            query.SetMaxResults(count);
            IList<T> results = query.List<T>();
            return results;
        }

        public int GetCountByConditions(string hql, List<string> conditions)
        {
            if (conditions != null)
            {
                foreach (string condition in conditions)
                {
                    hql += condition;
                }
            }

            IQuery query = SessionFactoryUtils.GetSession(HibernateTemplate.SessionFactory, true).CreateQuery(hql);
            object o = query.UniqueResult();
            return o == null ? 0 : int.Parse(o.ToString());
        }

        #endregion

        public ILog Logger { get; set; }
    }
}